﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Reflection;
using System.Data;
using PrintTemplate;
using Microsoft.Win32;

namespace PrintTax
{
    [ComVisible(true)]
    [Guid("78836B01-70AB-4940-82A1-E51AE55F932D")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof(IComPrint))]
    [ComSourceInterfaces(typeof(IComPrintEvent))]
    public class ComPrinter : UserControl, IComPrint, IObjectSafety
    {
        public bool Print(string businessName, string state, string detail, string time, string taxpayerName, string taxpayerNumber, string terminalId, string printerName, string templateFileName)
        {
            errMsg = string.Empty;
            try
            {
                if (string.IsNullOrWhiteSpace(templateFileName))
                {
                    throw new Exception("打印目标不能为空");
                }

                if (string.IsNullOrWhiteSpace(printerName))
                {
                    throw new Exception("打印机名称不能为空");
                }
                
                DateTime d;
                var isDatetime = DateTime.TryParse(time, out d);

                if (!isDatetime)
                {
                    throw new Exception("日期“time”格式不正确");
                }

                var rTemplateFileName = Path.IsPathRooted(templateFileName);
                if (!rTemplateFileName)
                {
                    templateFileName = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, templateFileName);
                }

                if (!SetDefaultPrinter(printerName))
                {
                    throw new Exception("设置打印失败");
                }
                    
                DataTable table = new DataTable();
                table.Columns.Add("businessName");
                table.Columns.Add("businessState");
                table.Columns.Add("businessDetail");
                table.Columns.Add("taxpayerNumber");
                table.Columns.Add("taxpayerName");
                table.Columns.Add("terId");
                table.Columns.Add("businessDate");
                var row = table.NewRow();
                row[0] = businessName;
                row[1] = state;
                row[2] = detail;
                row[3] = taxpayerNumber;
                row[4] = taxpayerName;
                row[5] = terminalId;
                row[6] = time;
                table.Rows.Add(row);

                //JObject jObject = new JObject();
                //jObject.Add("businessName", businessName);
                //jObject.Add("businessState", state);
                //jObject.Add("businessDetail", detail);
                //jObject.Add("taxpayerNumber", taxpayerNumber);
                //jObject.Add("taxpayerName", taxpayerName);
                //jObject.Add("terId", terminalId);
                //jObject.Add("businessDate", time);

                //MessageBox.Show(jObject.ToString());

                PrintTemplate.HtmlTagTemplate template = new PrintTemplate.HtmlTagTemplate();
                template.DataSource = table;//jObject;
                template.Formatter = new DataTableFormatter();//new JsonFormatter();
                template.Url = templateFileName;
                template.BeforePrint += (o, e) =>
                {
                    RegistryKey regInternetExplorer = null;
                    RegistryKey regPageSetup = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Internet Explorer\\PageSetup", true);
                    if (regPageSetup == null)
                    {
                        regInternetExplorer = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Internet Explorer", true);
                        regPageSetup = regInternetExplorer.CreateSubKey("PageSetup");
                        regInternetExplorer.Flush();
                    }
                    regPageSetup.SetValue("header", "");
                    regPageSetup.SetValue("footer", "");
                    regPageSetup.SetValue("margin_bottom", 0);
                    regPageSetup.SetValue("margin_left", 0);
                    regPageSetup.SetValue("margin_right", 0);
                    regPageSetup.SetValue("margin_top", 0);
                    regPageSetup.Flush();
                    regPageSetup.Close();
                    if (regInternetExplorer != null)
                        regInternetExplorer.Close();
                };
                template.AfterPrint += (o, e) => {
                    errMsg = e.Message;
                    if(PrintComplete != null)
                    PrintComplete.Invoke(e.Success, e.Message);
                };
                template.Print();
                return true;

            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return false;
            }
        }

        private string errMsg=  string.Empty;
        public string ErrMsg
        {
            get
            {
                return errMsg;
            }
        }

        public event PrintCompleteEventHandler PrintComplete;

        /// <summary>
        /// 设置默认打印机
        /// </summary>
        /// <param name="Name"></param>
        /// <returns></returns>
        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool SetDefaultPrinter(string name);

        #region IObjectSafety 成员

        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";
        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);
        private bool _fSafeForScripting = true;
        private Label label1;
        private bool _fSafeForInitializing = true;

        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;

            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK; pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }
            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;
            string strGUID = riid.ToString("B");

            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) && (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) && (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }
        #endregion

        private void InitializeComponent()
        {
            this.label1 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(45, 64);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(53, 12);
            this.label1.TabIndex = 0;
            this.label1.Text = "加载成功";
            // 
            // ComPrinter
            // 
            this.Controls.Add(this.label1);
            this.Name = "ComPrinter";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

    }
}
